using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Phoenix.Xna.Framework.Graphics.Animation;

namespace Phoenix.Xna.Framework.Graphics.Models
{
    public class SkinnedModelBone
    {
        public ushort Index { get; private set; }

        public string Name { get; private set; }

        public SkinnedModelBone Parent { get; internal set; }

        public SkinnedModelBoneCollection Children { get; internal set; }

        public Pose BindPose { get; private set; }

        public Matrix InverseBindPoseTransform { get; private set; }

        internal SkinnedModelBone(ushort index, string name, Pose bindPose, Matrix inverseBindPoseTransform)
        {
            Index = index;
            Name = name;
            BindPose = bindPose;
            InverseBindPoseTransform = inverseBindPoseTransform;
        }

        public void CopyBindPoseTo(Pose[] destination)
        {
            int boneIndex = 0;
            CopyBindPoseTo(destination, ref boneIndex);
        }

        private void CopyBindPoseTo(Pose[] destination, ref int boneIndex)
        {
            destination[boneIndex++] = BindPose;

            foreach (SkinnedModelBone bone in Children)
            {
                bone.CopyBindPoseTo(destination, ref boneIndex);
            }
        }

        internal static SkinnedModelBone Read(ContentReader input)
        {
            ushort index = input.ReadUInt16();
            string name = input.ReadString();
            Pose bindPose;
            bindPose.Translation = input.ReadVector3();
            bindPose.Orientation = input.ReadQuaternion();
            bindPose.Scale = input.ReadVector3();
            Matrix inverseBindPoseTransform = input.ReadMatrix();
            SkinnedModelBone skinnedBone = new SkinnedModelBone(index, name, bindPose, inverseBindPoseTransform);
            input.ReadSharedResource<SkinnedModelBone>(delegate(SkinnedModelBone parentBone)
            {
                skinnedBone.Parent = parentBone;
            });
            int numChildren = input.ReadInt32();
            List<SkinnedModelBone> childrenList = new List<SkinnedModelBone>(numChildren);

            for (int i = 0; i < numChildren; i++)
            {
                input.ReadSharedResource<SkinnedModelBone>(delegate(SkinnedModelBone childBone)
                {
                    childrenList.Add(childBone);
                });
            }

            skinnedBone.Children = new SkinnedModelBoneCollection(childrenList);
            return skinnedBone;
        }
    }
}